package com.zlyx.easy.http.handlers;

import org.springframework.web.bind.annotation.RequestMethod;

import com.fasterxml.jackson.core.type.TypeReference;
import com.zlyx.easy.core.jackson.JSONObject;
import com.zlyx.easy.core.map.EasyMap;
import com.zlyx.easy.core.map.Maps;
import com.zlyx.easy.http.executor.HttpExecutor;
import com.zlyx.easy.http.executor.defaults.DefaultHttpExecutor;
import com.zlyx.easy.http.models.RequestModel;

/**
 * 
 * @Auth 赵光
 * @Describle
 * @2019年12月25日
 */
public class DefaultMappingHandler extends AbstractMappingHandler {

	private static EasyMap<String, AbstractMappingHandler> mappingHandlers = Maps.newMap();

	private static DefaultMappingHandler defaultMappingHandler;

	/**
	 * 私有化构造方法
	 * 
	 * @param httpService
	 */
	private DefaultMappingHandler(HttpExecutor httpService) {
		super(httpService);
	}

	@Override
	public Object handleMapping(RequestModel requestModel) throws Exception {
		String methodName = requestModel.getMethod().name();
		AbstractMappingHandler mappingHandler = mappingHandlers.get(methodName);
		if (mappingHandler == null) {
			if ("GET".equals(methodName)) {
				mappingHandler = new GetMappingHandler(httpService);
			} else if ("POST".equals(methodName)) {
				mappingHandler = new PostMappingHandler(httpService);
			} else if ("DELETE".equals(methodName)) {
				mappingHandler = new DeleteMappingHandler(httpService);
			} else if ("PUT".equals(methodName)) {
				mappingHandler = new PutMappingHandler(httpService);
			}
			mappingHandlers.put(methodName, mappingHandler);
		}
		return mappingHandler.handleMapping(requestModel);
	}

	/**
	 * 处理请求
	 *
	 * @param requestMethod  类型
	 * @param mappingHandler 处理器
	 * @return
	 */
	public DefaultMappingHandler addHandleMapping(RequestMethod requestMethod, AbstractMappingHandler mappingHandler) {
		mappingHandlers.put(requestMethod.name(), mappingHandler);
		return this;
	}

	/**
	 * 添加自定义mappingHandler
	 * 
	 * @param requestMethod  类型
	 * @param mappingHandler 处理器
	 * @return
	 */
	public AbstractMappingHandler getHandleMapping(RequestMethod requestMethod) {
		return mappingHandlers.get(requestMethod.name());
	}

	/**
	 * 构造默认DefaultMappingHandler
	 * 
	 * @param httpService
	 * @return
	 */
	public static DefaultMappingHandler getDefaultMappingHandler() {
		return getDefaultMappingHandler(new DefaultHttpExecutor());
	}

	/**
	 * 构造带参DefaultMappingHandler
	 * 
	 * @param httpService
	 * @return
	 */
	public static DefaultMappingHandler getDefaultMappingHandler(HttpExecutor httpService) {
		if (defaultMappingHandler == null
				|| (httpService != null && httpService.getClass() != DefaultHttpExecutor.class)) {
			defaultMappingHandler = new DefaultMappingHandler(httpService);
		}
		return defaultMappingHandler;
	}

	/**
	 * 处理请求
	 * 
	 * @param <T>
	 * @param requestModel
	 * @param typeReference
	 * @return
	 * @throws Exception
	 */
	public static <T> T handleMapping(RequestModel requestModel, TypeReference<T> typeReference) throws Exception {
		String response = (String) getDefaultMappingHandler().handleMapping(requestModel);
		return JSONObject.parseObject(response, typeReference);
	}

	/**
	 * 处理请求
	 * 
	 * @param model
	 * @param cls
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static <T> T handleMapping(RequestModel requestModel, Class<T> cls) throws Exception {
		return (T) getDefaultMappingHandler().handleMapping(requestModel);
	}

}